package com.liuya.safe.entitle.controller;

import java.util.Collection;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.liuya.base.BaseController;
import com.liuya.common.exception.EntityExistException;
import com.liuya.common.SpringUtils;
import com.liuya.common.WebUtil;
import com.liuya.safe.entitle.handler.QueryEntitlementHandler;
import com.liuya.safe.entitle.service.EntitleManagerService;
import com.liuya.safe.entitle.service.PrivilegeManagerService;
import com.liuya.safe.model.SafePrivilege;
import com.liuya.safe.model.SafeQuery;
import com.liuya.safe.model.SafeQueryEntitlement;
import com.liuya.safe.model.SafeUserCategory;
import com.liuya.safe.policy.service.QueryManagerService;
import com.liuya.safe.policy.service.UserCategoryManagerService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * 权限管理
 * @author liuya
 * @date 20160826
 */
@Controller
@Api(value = "权限管理", description = "权限管理")
@RequestMapping(value = "queryEntitlement")
//@SessionAttributes("handler")
public class QueryEntitlementContrller extends BaseController {

    private static final Log log = LogFactory.getLog(QueryEntitlementContrller.class);

    @ApiOperation(value = "查询会话")
//    @RequiresPermissions("sys.nonRolePriviMng.decision")
    @RequestMapping(value = "/decision")
    public Object decision(HttpServletRequest req, HttpServletResponse rep, ModelMap map){
        QueryEntitlementHandler handler = getHandler(req);
        map.addAttribute("handler", handler);

        return "privilege/queryEntitlement";
    }

    @ApiOperation(value = "查询会话")
//    @RequiresPermissions("sys.nonRolePriviMng.loadEntitlements")
    @RequestMapping(value = "/loadEntitlements")
    public Object loadEntitlements(HttpServletRequest req, HttpServletResponse rep, ModelMap map){
        QueryEntitlementHandler handler = getHandler(req);
        map.addAttribute("handler", handler);

        return "privilege/queryEntitlementTable";
    }

    @ApiOperation(value = "查询会话")
//    @RequiresPermissions("sys.nonRolePriviMng.getEntitlement")
    @RequestMapping(value = "/getEntitlement")
    public Object getEntitlement(HttpServletRequest req, HttpServletResponse rep, ModelMap map){
        QueryEntitlementHandler handler = getHandler(req);
        map.addAttribute("handler", handler);

        int index = WebUtil.getIntParameter(req, "index", -23);
        if (index >= 0) {
            SafeQueryEntitlement entitlement = (SafeQueryEntitlement) handler.getQueryEntitlements().get(index);
            req.setAttribute("entitlement", entitlement);
        }

        return "privilege/editQueryEntitlement";
    }

    @ApiOperation(value = "查询会话")
//    @RequiresPermissions("sys.nonRolePriviMng.returns")
    @RequestMapping(value = "/returns")
    public Object returns(HttpServletRequest req, HttpServletResponse rep, ModelMap map){
        QueryEntitlementHandler handler = getHandler(req);
        map.addAttribute("handler", handler);

        String gotoUrl = "./nonRolePriviMng/openTree.do";
        if (handler.getPrivilege().getType() == 0) {
            gotoUrl = "./privilegeMng/openTree.do";
        }
        String key = getHandlerKey(req);
        req.getSession().removeAttribute(key);

        return "redirect:/" + gotoUrl;
    }

    @ApiOperation(value = "查询会话")
//    @RequiresPermissions("sys.nonRolePriviMng.addEntitle")
    @RequestMapping(value = "/addEntitle")
    @ResponseBody
    public Object addEntitle(HttpServletRequest req, HttpServletResponse rep, ModelMap map){
        QueryEntitlementHandler handler = getHandler(req);
        SafeQueryEntitlement entitle = getQueryEntitlement(req);
        handler.addEntitle(entitle);
        updateHandler(handler, req);
        map.addAttribute("handler", handler);
        return true;
    }

    @ApiOperation(value = "查询会话")
//    @RequiresPermissions("sys.nonRolePriviMng.editEntitle")
    @RequestMapping(value = "/editEntitle")
    @ResponseBody
    public Object editEntitle(HttpServletRequest req, HttpServletResponse rep, ModelMap map){
        QueryEntitlementHandler handler = getHandler(req);

        int index = WebUtil.getIntParameter(req, "index", 0);
        SafeQueryEntitlement entitle = getQueryEntitlement(req);
        handler.updateEntitle(index, entitle);

        map.addAttribute("handler", handler);
        updateHandler(handler, req);
        return true;
    }

    @ApiOperation(value = "查询会话")
//    @RequiresPermissions("sys.nonRolePriviMng.moveEntitle")
    @RequestMapping(value = "/moveEntitle")
    @ResponseBody
    public Object moveEntitle(HttpServletRequest req, HttpServletResponse rep, ModelMap map){
        QueryEntitlementHandler handler = getHandler(req);
        map.addAttribute("handler", handler);

        int index = WebUtil.getIntParameter(req, "index", 0);
        String direct = req.getParameter("direct");
        handler.moveEntitle(index, direct);
        updateHandler(handler, req);
        return true;
    }

    @ApiOperation(value = "查询会话")
//    @RequiresPermissions("sys.nonRolePriviMng.deleteEntitle")
    @RequestMapping(value = "/deleteEntitle")
    @ResponseBody
    public Object deleteEntitle(HttpServletRequest req, HttpServletResponse rep, ModelMap map){
        QueryEntitlementHandler handler = getHandler(req);
        map.addAttribute("handler", handler);

        int index = WebUtil.getIntParameter(req, "index", 0);
        handler.deleteEntitle(index);
        updateHandler(handler, req);
        return true;
    }

    @ApiOperation(value = "查询会话")
//    @RequiresPermissions("sys.nonRolePriviMng.save")
    @RequestMapping(value = "/save")
    @ResponseBody
    public Object save(HttpServletRequest req, HttpServletResponse rep, ModelMap map){
        QueryEntitlementHandler handler = getHandler(req);
        map.addAttribute("handler", handler);

        try {
            handler.save();
        } catch (EntityExistException e) {
            log.error("", e);
        }
        // clean session
        String key = getHandlerKey(req);
        req.getSession().removeAttribute(key);

        return true;
    }

    public QueryEntitlementHandler createHandler(HttpServletRequest req) {
        String id = WebUtil.getStringParameter(req, "id", "-23");

        PrivilegeManagerService pvlgMng = (PrivilegeManagerService) SpringUtils.getBean("privilegeManagerService");
        EntitleManagerService entitleMng = (EntitleManagerService) SpringUtils.getBean("entitleManagerService");
//        QueryManagerService queryMng = (QueryManagerService) SpringUtils.getBean("queryManagerService");

        SafePrivilege pvlg = pvlgMng.getPrivilege(id);
        Collection entitlements = entitleMng.getQueryEntitlements(id);

        if (log.isDebugEnabled()) {
            log.debug("id=" + id + ", name=" + pvlg.getName());
        }

        return new QueryEntitlementHandler(pvlg, entitlements);
    }

    public String getHandlerKey(HttpServletRequest req) {
        int id = WebUtil.getIntParameter(req, "id", 0);
        return "_$safeQueryEntitlement_" + id;
    }

    private QueryEntitlementHandler getHandler(HttpServletRequest req){
        String oper = req.getParameter("oper");
        String key = getHandlerKey(req);
        Object obj = req.getSession().getAttribute(key);
        QueryEntitlementHandler handler = null;
        if (obj == null || "loadFresh".equals(oper)) {
            handler = createHandler(req);
            // save into session, will be removed when policy is saved
            req.getSession().setAttribute(key, handler);
        } else {
            handler = (QueryEntitlementHandler) obj;
        }
        return handler;
    }

    private void updateHandler(QueryEntitlementHandler handler, HttpServletRequest req){
        String key = getHandlerKey(req);
        req.getSession().setAttribute(key, handler);
    }

    private SafeQueryEntitlement getQueryEntitlement(HttpServletRequest req) {
        String description = req.getParameter("description");
        String queryId = WebUtil.getStringParameter(req, "queryId", "-23");
        String ucId = WebUtil.getStringParameter(req, "ucId", "-23");
        String id = WebUtil.getStringParameter(req, "id", "-23");

        QueryManagerService queryManager = (QueryManagerService) SpringUtils.getBean("queryManagerService");
        SafeQuery query = queryManager.getQuery(queryId);
        UserCategoryManagerService userCategoryManager = (UserCategoryManagerService) SpringUtils.getBean("userCategoryManagerService");
        SafeUserCategory userCategory = userCategoryManager.getUserCategory(ucId);

        SafeQueryEntitlement entitle = new SafeQueryEntitlement();
        entitle.setDescription(description);
        entitle.setPrivilegeId(id);
        entitle.setQueryId(queryId);
        entitle.setUserCategoryId(ucId);
        entitle.setQuery(query);
        entitle.setUserCategory(userCategory);

        return entitle;
    }
}
